package com.atguigu.jvm.chap02;

/**
 * @author Taeyang
 * @date 2025/3/27
 */
public class App {

    public static void main(String[] args) {
        // 1. 创建对象实例
        //  - 触发类加载（若Car类未被加载）
        //  - 堆内存分配策略：指针碰撞（Serial、ParNew等带压缩的GC）或空闲列表（CMS）
        //  - 对象头结构：
        //    ┌───────────────┐
        //    │   Mark Word   │ → 存储hashCode、GC年龄、锁状态标志等（64位系统占8字节）
        //    ├───────────────┤
        //    │  Class Pointer│ → 指向方法区的Car类元数据（开启压缩指针占4字节，否则8字节）
        //    ├───────────────┤
        //    │  实例数据      │ → 对象包含的字段数据
        //    ├───────────────┤
        //    │  对齐填充      │ → 保证对象大小是8字节的整数倍（可选）
        //    └───────────────┘
        Car car = new Car();

        // 2. 反射获取类的Class对象（元数据）
        //  - Class对象在类加载的"加载"阶段创建，存储在元空间（JDK8+）
        //  - 每个类有且只有一个Class对象（单例模式）
        //  - 反射性能提示：获取Class对象开销小，但Method.invoke()调用比直接调用慢2-3倍
        Class<? extends Car> aClass = car.getClass();

        // 3. 输出Class对象信息
        //  - 输出格式遵循Class.toString()规范：class 全限定类名
        //  - 示例输出：class com.example.Car（普通类）/ interface java.util.List（接口）
        System.out.println(aClass);

        // 4. 获取加载该类的类加载器（ClassLoader）
        //  - 类加载双亲委派流程：
        //    1. AppClassLoader → ExtClassLoader → BootstrapClassLoader（实际无Java类实例）
        //    2. 父加载器无法加载时，才由子加载器尝试加载
        //  - 注意：BootstrapClassLoader由C++实现，Java中显示为null
        ClassLoader classLoader = aClass.getClassLoader();

        // 5. 输出类加载器信息
        //  - 典型输出：
        //    sun.misc.Launcher$AppClassLoader@18b4aac2 → 应用类加载器
        //    sun.misc.Launcher$ExtClassLoader@1540e19d  → 扩展类加载器
        //    null → 由Bootstrap类加载器加载（如java.lang.String）
        System.out.println(classLoader);

        // 6. 数组类的类加载器验证
        //  - 数组类特殊性：
        //    a. 由JVM运行时自动生成，类名格式：[元素类型签名（如[I表示int数组）
        //    b. 数组类的ClassLoader与其元素类型一致：
        //       - 元素是基本类型 → null（视为Bootstrap加载）
        //       - 元素是引用类型 → 元素类的ClassLoader
        //  - 示例：int[]类加载器为null，String[]类加载器与String类相同（Bootstrap）
        int[] arr = {1, 2, 3};
        System.out.println(arr.getClass().getClassLoader()); // 输出：null

        // 补充验证引用类型数组：
        String[] strArr = {"a", "b"};
        System.out.println(strArr.getClass().getClassLoader()); // 输出：null（String由Bootstrap加载）

        // 自定义类数组验证：
        Car[] cars = new Car[2];
        System.out.println(cars.getClass().getClassLoader()); // 输出：与Car类的加载器一致

        // 类加载器（应用程序类加载器）的上级（扩展类加载器）
        System.out.println(classLoader.getParent());
        // 类加载器的上级（扩展类加载器）的上级（启动类加载器 C++写的，输出为null）
        System.out.println(classLoader.getParent().getParent());
    }
}
